package main

import (
	"net/http"

	log "github.com/kpango/glg"
)

func Serve(addr string, admin *Admin) {
	server := &http.Server{
		Addr:    addr,
		Handler: admin,
	}
	server.ListenAndServe()
}

type Admin struct {
	version *Version
	rules   *RuleList
	auth    *Authenticator
}

func NewAdmin() (*Admin, error) {
	admin := &Admin{
		version: &Version{"1.0", "1.0"},
		rules:   new(RuleList),
		auth:    new(Authenticator),
	}

	rules, err := NewRules(*RuleFile)
	if err != nil {
		return nil, err
	}
	admin.rules = rules
	admin.rules.ReloadIfModified(*RuleFile)

	auth, err := NewAuthenticator(*PasswdFile)
	if err != nil {
		return nil, err
	}
	admin.auth = auth
	admin.auth.ReloadIfModified(*PasswdFile)

	return admin, nil
}

func (a *Admin) Close() {
	a.auth.CloseWatcher()
	a.rules.CloseWatcher()
}

func (a *Admin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path := r.URL.Path
	method := r.FormValue("method")
	log.Infof("Admin.ServeHTTP: receive %s request from %s. method: %s, url:%s",
		r.Method, r.RemoteAddr, r.FormValue("method"), r.URL.String())

	if path != "/rfdService" {
		w.WriteHeader(404)
		w.Write([]byte("unsolved request path"))
		return
	}

	err := a.auth.Authenticate(r)
	if err != nil {
		log.Errorf("Admin.Auth: auth fail, addr: %s, error: %v", r.RemoteAddr, err)
		w.WriteHeader(404)
		w.Write([]byte(err.Error()))
		return
	}

	switch r.Method {
	case "POST":
		if method == "setVersion" {
			a.version.SetVersion(w, r)
		}
		if method == "addRule" {
			a.rules.AddRule(w, r)
		}
		if method == "disableRule" {
			a.rules.Disable(w, r)
		}
	case "GET":
		if method == "checkUpdate" {
			a.version.CheckUpdate(w, r)
		}
		if method == "checkAvailable" {
			a.rules.CheckAvailable(w, r)
		}
		if method == "getRules" {
			a.rules.GetRules(w, r)
		}
	}
}
